package com.ilioili.waterfall;

import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;

import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.Scroller;

public class WaterFall extends ViewGroup implements Observer{
	
	
	
	private Adapter adapter;
	private GestureDetector detector;
	/**
	 * 最上面可见的位置，FreshView的上边界，如果没有FreshView则为headView的上边界，如果都没有则为ItemList的上边界，即0
	 */
	private int topBound;
	
	/**
	 * onScrll可以滑动的上边界
	 */
	private int scrollTopLimit;
	/**
	 * onScrll可以滑动的下边界
	 */
	private int scrollBottomLimit = Integer.MAX_VALUE;
	
	/**
	 * fling滑动的时候的curY的最下边界（最大值）
	 */
	private int flingBottomLimit = Integer.MAX_VALUE;
	/**
	 * fling滑动的时候的curY的最上边界（最小值）
	 */
	private int flingTopLimit;
	
	private Item[] bottomItems;
	/**
	 * 子空间高度Measure的参数
	 */
	private int childHeightMeasureSpec;
	/**
	 * 子空间宽度Measure的参数
	 */
	private int childWidthMeasureSpec;
	/**
	 * Item的View添加到此集合，不包含headView和footView，用于View复用
	 */
	private ArrayList<View> itemViewList;
	/**
	 * 当前滑动的位置
	 */
	private int curY = 0;
	
	public static final int DEFAULT_EXTRA_SIZE = 100;

	/**
	 * ACTION_DOWN的时候记录坐标，用于判断事件是否要拦截
	 */
	private float firstFingerY;
	
	/**
	 * ACTION_DOWN的时候记录坐标，用于判断事件是否要拦截
	 */
	private float firstFingerX;
	
	/**
	 * 是否可以刷新，当可以刷新时，flingTopLimit的�?和onScrollTopLimit�?��，可以看见headView
	 */
	private boolean freshable = true;
	
	private View freshView;
	
	private OnGestureListener gestureListener = new GestureDetector.SimpleOnGestureListener(){
		@Override
		public boolean onDown(MotionEvent e) {
			return true;
		}
		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) {
			if(scroller.isFinished()){
				scroller.fling(0, curY, 0, (int)-velocityY, 0, 0, curY-5000, curY+5000);
				flingStarted = true;
				postInvalidate();//会调用computScroll()
				return true;
			}else{
				return false;
			}
			
		}
		@Override
		public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,float distanceY) {
			scrollTo(0, (int)(curY+distanceY));//会调用onScrollChanged()
			computePreState();
			return true;
		}
		
	};
	/**
	 * 回调当前手指抬起后将要进行的操作
	 */
	private void computePreState(){
		if(stateListener==null) return;
		if(!isLoading){
			if(curY+viewHeight>=itemsBottomBound+loadMoreView.getMeasuredHeight()){
				if(isLoading){
					stateListener.getPreState(StateListener.UP_TO_LOAD_MORE);
				}
			}else if(curY+viewHeight>itemsBottomBound){
				if(isLoading)
				stateListener.getPreState(StateListener.UP_TO_CANCEL_LOAD_MORE);
			}
		}
		if(!isFreshing){
			if(curY <= topBound){
				stateListener.getPreState(StateListener.UP_TO_FRESH);
			}else if(curY<=headViewHeight){
				stateListener.getPreState(StateListener.UP_TO_CANCEL_FRESH);
			}
		}
		
	}
	
	public boolean isOnFling(){
		if(flingStarted && !scroller.isFinished()){
			return true;
		}else{
			flingStarted = false;
			return false;
		}
	}
	
	private View headView;
	
	private int headViewHeight;
	
	private int headViewTop;

	private ArrayList<Item> idleItemList;
	/**
	 * �?��不可见的View添加到此集合里面，用于View复用
	 */
	private ArrayList<View> itemRecycler;
	/**
	 */
	private boolean flingStarted;
	/**
	 * 是否向下滑动
	 */
	private boolean isDownward = true;
	/**
	 * 是否正在刷新，在OnTouchEnvent()中，如果在调用stateListener.startFresh()之前置为true，对滑动边界的设定有影响
	 */
	private boolean isFreshing;
	
	private boolean isFreshViewMeasured;
	
	/**
	 * 调用完initItems()后，设置为true，用于在onMeasure(int agr0, int agr1)里防止重复测�?
	 */
	private boolean isInitItemsDone;
	
	/**
	 * 是否正在刷新，在OnTouchEnvent()中，如果在调用stateListener.startLoadMore()之前置为true，对滑动边界的设定有影响
	 */
	private boolean isLoading;
	
	private boolean isLoadMoreViewMeasured;
	/**
	 * 程序在调用measureChildren时此值为true
	 */
	private ArrayList<Item> itemList;
	
	private int itemWidth;
	/**
	 * 是否可以上拉加载
	 */
	private boolean loadable = true;
	/**
	 * 下拉刷新的View
	 */
	private View loadMoreView;
	/**
	 * 瀑布流的列数
	 */
	private int N = 2;
	
	/**
	 * ItemList的最下边界
	 */
	private int itemsBottomBound;
	
	private Scroller scroller;
	
	private StateListener stateListener;
	
	private Item[] topItems;
	
	
	private int viewHeight;
	
	private int viewWidth;
	
	private int minTouchSlop;
	
	public WaterFall(Context context) {
		super(context);
		 final ViewConfiguration configuration = ViewConfiguration.get(context);
		 minTouchSlop = configuration.getScaledTouchSlop();
		init();
	}
	
	
	public WaterFall(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}
	/**
	 * 取消刷新
	 */
	public void cancelFreshing(){
		isFreshing = false;
		if(freshable){
			scrollTopLimit = topBound;
		}else{
			scrollTopLimit = headViewTop;
		}
		flingTopLimit = headViewTop;
		flingBottomLimit = scrollBottomLimit - loadMoreView.getMeasuredHeight();
		if(curY<headViewTop){
			scroller.startScroll(0, curY, 0, headViewTop-curY, 1000);
			postInvalidate();
		}
	}
	
	/**
	 * 如果loadMoreView可见，则滑动至不可见，如果loadMoreView不可见，则不处理
	 * 修改fling的下边界
	 */
	public void cancelLoading(){
		if(loadMoreView==null) return;
		isLoading = false;
		flingBottomLimit = scrollBottomLimit-loadMoreView.getMeasuredHeight();
		if(curY+viewHeight>itemsBottomBound){
			scroller.startScroll(0, curY, 0, itemsBottomBound-viewHeight-curY, 1000);
			postInvalidate();
		}
		loadMoreView.setVisibility(View.GONE);
	}
	

	
	/**
	 * 添加新的Item之后要计算ItemList的下边界
	 */
	final private void computeBottom(){
		for(int i=0; i<N; i++){
			if(bottomItems[i]!=null){
				if(bottomItems[i].bottom>itemsBottomBound){
					itemsBottomBound=bottomItems[i].bottom;
				}
			}else{
				break;
			}
		}
	}
	private void computeChildVisibity(){
//		long start = System.currentTimeMillis();
		Item item = null;
		int col = 0;
		if(itemList.isEmpty()){
			return;
		}else if(isDownward){//向下滑动
			col = getNextDownWhenDown();
			while(bottomItems[col].top>curY+viewHeight && bottomItems[col].upItem!=null){
				p("回收Item"+bottomItems[col].index);
				bottomItems[col].v.setVisibility(View.GONE);
				itemRecycler.add(bottomItems[col].v);
				bottomItems[col] = bottomItems[col].upItem;
				col = getNextDownWhenDown();
			}
			col = getNextUpWhenDown();
			while(topItems[col].top>curY && topItems[col].upItem!=null){
				p("添加Item"+topItems[col].index);
				item = topItems[col].upItem;
				topItems[col] = item;
				item.v = obtainView(item.index);
				item.v.layout(item.left, item.top, item.right, item.bottom);
			}
			
		}else{//向上滑动
			col = getNextUpWhenUp();
			while(topItems[col].bottom<curY && topItems[col].downItem!=null){
//				Log.e("","回收Item"+topItems[col].index);
				topItems[col].v.setVisibility(View.GONE);
				itemRecycler.add(topItems[col].v);
				topItems[col] = topItems[col].downItem;
				col = getNextUpWhenUp();
			}
			col = getNextDownWhenUp();
			while(bottomItems[col].bottom<curY+viewHeight){//�?���?��下边界小于底部，有空缺出来了
				p("添加Item"+bottomItems[col].index);
				item = bottomItems[col].downItem;
				if(null==item){
					if(itemList.size()<adapter.getCount()){
						item = obtainItem();
						itemList.add(item);
						item.index = itemList.size()-1;
						item.v = obtainView(item.index);
						item.top = bottomItems[col].bottom;
						item.upItem = bottomItems[col];
						bottomItems[col].downItem = item;
						bottomItems[col] = item;
						item.left = col*itemWidth;
						item.right = item.left+itemWidth;
						item.bottom = item.top+item.v.getMeasuredHeight();
						
						if(itemList.size()==adapter.getCount()){
							computeBottom();
							setBottomConfigs();
						}
					}else{
						break;
					}
				}else{
					item.v = obtainView(item.index);
					bottomItems[col] = item;
				}
				item.v.layout(item.left, item.top, item.right, item.bottom);
				col = getNextDownWhenUp();
				computeBottom();
			}
		}
	}
	/**
	 * �?��的Item加载完成后，设置LoadView为可见，并且放置好位置（分是否慢�?��内容�?
	 * 设置fling的下边界
	 */
	private void setBottomConfigs(){
		p("setBottomConfigs");
		if(null==loadMoreView&&loadable){
			if(headViewHeight+itemsBottomBound>viewHeight){//超出�?��
				scrollBottomLimit = itemsBottomBound-viewHeight;
			}else{
				scrollBottomLimit = 0;
			}
			flingBottomLimit = scrollBottomLimit;
		}else{
			loadMoreView.setVisibility(View.VISIBLE);
			if(headViewHeight+itemsBottomBound>viewHeight){//超出�?��
				loadMoreView.layout(0, itemsBottomBound, viewWidth, itemsBottomBound+loadMoreView.getMeasuredHeight());
				loadMoreView.invalidate();
				scrollBottomLimit = itemsBottomBound+loadMoreView.getMeasuredHeight()-viewHeight;
				if(isLoading){
					flingBottomLimit = scrollBottomLimit;
				}else{
					flingBottomLimit = scrollBottomLimit-loadMoreView.getMeasuredHeight();
				}
			}else{
				loadMoreView.layout(0, viewHeight-headViewHeight, viewWidth, viewHeight-headViewHeight+loadMoreView.getMeasuredHeight());
				scrollBottomLimit = loadMoreView.getMeasuredHeight();
				flingBottomLimit = 0;
			}
		}
		p("flingBottomLimit"+flingBottomLimit);
		p("scrollBottomLimit"+scrollBottomLimit);
	}
	
	private void initBottomConfigs(){
		p("initBottomConfigs");
		flingBottomLimit = Integer.MAX_VALUE;
		scrollBottomLimit = Integer.MAX_VALUE;
		if(null!=loadMoreView){
			loadMoreView.setVisibility(View.GONE);
		}
	}
	
	@Override
	public void computeScroll() {
		super.computeScroll();
		if(scroller.computeScrollOffset()){
			scrollTo(0, scroller.getCurrY());
		}
	}
	
	public void freshHeadView() {
		int widthMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY);
		measureHeadView(widthMeasureSpec);
	}
	
	public int getColumn(){
		return N;
	}
	final private int getNextDownWhenDown(){
		int index = 0;
		for(int i=1; i<N; i++){
			if(bottomItems[i].top>bottomItems[index].top){
				index = i;
			}
		}
		return index;
	}
	final private int getNextDownWhenUp(){
		for(int i=0; i<N; i++){
			if(bottomItems[i]==null){
				return i;
			}
		}
		int index = 0;
		for(int i=1; i<N; i++){
			if(bottomItems[i].bottom<bottomItems[index].bottom){
				index = i;
			}
		}
		return index;
	}
	final private int getNextUpWhenDown(){
		int index = 0;
		for(int i=1; i<N; i++){
			if(topItems[i].top>topItems[index].top){
				index = i;
			}
		}
		return index;
	}

	final private int getNextUpWhenUp(){
		int index = 0;
		for(int i=1; i<N; i++){
			if(topItems[i].bottom<topItems[index].bottom){
				index = i;
			}
		}
		return index;
	}
	
	@SuppressLint("NewApi")
	private void init(){
		p("init");
		itemRecycler = new ArrayList<View>();
		itemViewList = new ArrayList<View>();
		itemList = new ArrayList<Item>();
		idleItemList = new ArrayList<Item>();
		detector = new GestureDetector(getContext(), gestureListener);
		if(android.os.Build.VERSION.SDK_INT>10){
			scroller = new Scroller(getContext(),null,true);
		}else{
			scroller = new Scroller(getContext(),null);
		}
	}
	
	private void initItems(){
		p("initItems()");
		if(isInitItemsDone || adapter.getCount()==0){
			return;
		}else{
			p("initItems() data loading");
			int num = adapter.getCount();
			for(int i=0; i<num; i++){
				isInitItemsDone = true;
				int colum = getNextDownWhenUp();
				Item item = null;
				if(bottomItems[colum]==null){
					item = obtainItem();
					topItems[colum] = item;
					item.top = 0;
				}else{
					if(bottomItems[colum].bottom>curY+viewHeight){
						break;
					}else{
						item = obtainItem();
						item.top = bottomItems[colum].bottom;
						item.upItem = bottomItems[colum];
						bottomItems[colum].downItem = item;
					}
				}
				itemList.add(item);
				item.v = obtainView(i);
				item.left = colum*itemWidth;
				item.right = item.left+itemWidth;
				item.bottom = item.top+item.v.getMeasuredHeight();
				bottomItems[colum] = item;
				item.v.layout(item.left, item.top, item.right, item.bottom);
				item.index = i;
				p("添加Item"+item.index);
			}
			itemsBottomBound = 0;
			computeBottom();
			if(itemList.size()==adapter.getCount()){
				setBottomConfigs();
			}
		}
	}
	
	final private boolean isAllItemsLoaded(){
		if(adapter.getCount()==0){
			return false;
		}else{
			return itemList.size()==adapter.getCount();
		}
		
	}
	
	/**
	 * @return true表示向下滑动，否则认为是向上滑动（优化回收策略）
	 */
	public boolean isDownWard(){
		return isDownward;
	}
	public boolean isFreshing(){
		return isFreshing;
	}

	/**
	 * @param position
	 * @param extraBound 超出边界在extraBound之内的认为可�?
	 * @return
	 */
	public boolean isItemVisible(int position, int extraBound){
		if(position>=itemList.size()){
			return true;
		}
		Item item = itemList.get(position);
		if(item.bottom==0){
			return true;
		}else{
			return item.isVisible(curY, viewHeight, DEFAULT_EXTRA_SIZE);
		}
	}
	
	public boolean isLoaing(){
		return isLoading;
	}

	private void measureFreshViewIfNotMeasured(int widthMeasureSpec) {
		if(null!=freshView && !isFreshViewMeasured){
			int heightMeasureSpec = MeasureSpec.makeMeasureSpec(LayoutParams.WRAP_CONTENT, MeasureSpec.UNSPECIFIED);
			freshView.measure(widthMeasureSpec, heightMeasureSpec);
			topBound = headViewTop-freshView.getMeasuredHeight();
			if(freshable){
				scrollTopLimit = topBound;
			}else{
				scrollTopLimit = headViewTop;
			}
			freshView.layout(0, topBound, freshView.getMeasuredWidth(), headViewTop);
			isFreshViewMeasured = true;
		}
	}
	
	private void measureHeadView(int widthMeasureSpec) {
		p("measureHeadView()");
		if(null==headView){
			return;
		}
		
		LayoutParams params = headView.getLayoutParams();
		if(null==headView.getLayoutParams()){
			params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
			headView.setLayoutParams(params);
		}
		int heightSpec = 0;
		if(params.height==LayoutParams.WRAP_CONTENT){
			heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
		}else{
			heightSpec = MeasureSpec.makeMeasureSpec(params.height, MeasureSpec.EXACTLY);
		}
		int widthSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY);
		headView.measure(widthSpec, heightSpec);
		if(headViewHeight != headView.getMeasuredHeight()){
			headViewHeight = headView.getMeasuredHeight();
			headViewTop = -headViewHeight;
			flingTopLimit = headViewTop;
			topBound = headViewTop-freshView.getMeasuredHeight();
			scrollTopLimit = topBound;
			headView.layout(0, headViewTop, headView.getMeasuredWidth(), 0);
			freshView.layout(0, topBound, freshView.getMeasuredWidth(), headViewTop);
			scrollTo(0, headViewTop);
		}
	}
	
	private void measureLoadMoreViewIfNotMeasured(int widthMeasureSpec) {
		if(null!=loadMoreView && !isLoadMoreViewMeasured){
			int heightMeasureSpec = MeasureSpec.makeMeasureSpec(LayoutParams.WRAP_CONTENT, MeasureSpec.UNSPECIFIED);
			loadMoreView.measure(widthMeasureSpec, heightMeasureSpec);
			isLoadMoreViewMeasured = true;
		}
	}
	/**
	 * 如果没有滑动到可以触发刷新的位置则返回到刷新不可见位�?
	 * 如果没有滑动到可以触发加载更多的位置则返回到LoadMoreView不可见位�?
	 */
	private void modifyOverBound() {
		if(null!=freshView){
			if(!isFreshing){
				if(curY <= topBound){
					if(null!=stateListener){
						isFreshing = true;
						flingTopLimit = scrollTopLimit;
						stateListener.startFresh();
					}
				}else if(curY<headViewTop && curY>topBound){
					flingTopLimit = headViewHeight;
					scroller.forceFinished(true);
					scroller.startScroll(0, curY, 0, headViewTop-curY, 500);
					postInvalidate();
				}
			}
		}
		if(null!=loadMoreView){
			if(!isLoading && curY+viewHeight >= itemsBottomBound+loadMoreView.getMeasuredHeight()){
				if(null!=stateListener){
					isLoading = true;
					flingBottomLimit = scrollBottomLimit;
					scrollTo(0, flingBottomLimit);
					stateListener.startLoadMore();
				}
			}else if(curY+viewHeight>itemsBottomBound){//loadMoreView可见，动画弹�?
				flingBottomLimit = scrollBottomLimit-loadMoreView.getMeasuredHeight();
				scroller.forceFinished(true);
				scroller.startScroll(0, curY, 0, itemsBottomBound-viewHeight-curY, 500);
				postInvalidate();
			}
		}
	}
	
	final private Item obtainItem(){
		Item item = null;
		if(idleItemList.isEmpty()){
			item =  new Item();
		}else{
			item = idleItemList.get(0);
			item.reset();
			idleItemList.remove(0);
		}
		return item;
	}
	
	
	final private View obtainView(int i) {
		View v = null;
		if(itemRecycler.isEmpty()){
			v = adapter.getView(null,this,i);
			itemViewList.add(v);
			addView(v);
		}else{
			v = itemRecycler.get(0);
			v = adapter.getView(v, this, i);
			v.setVisibility(View.VISIBLE);
			itemRecycler.remove(0);
		}
		v.forceLayout();
		v.measure(childWidthMeasureSpec, childHeightMeasureSpec);
		return v;
	}
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		if(ev.getAction()==MotionEvent.ACTION_DOWN){
			firstFingerY = ev.getY();
			firstFingerX = ev.getX();
			detector.onTouchEvent(ev);//让Detector记录Down事件，否则onScroll的最后一次事件是上次的Up事件的位�?
			scroller.forceFinished(true);
		}
		//判断滑动方向为竖直方向则拦截事件
		if(ev.getAction()==MotionEvent.ACTION_MOVE
			&& Math.abs(ev.getY()-firstFingerY)+Math.abs(ev.getX()-firstFingerX)>minTouchSlop 
					&& Math.abs(ev.getY()-firstFingerY)>Math.abs(ev.getX()-firstFingerX)){
			return true;
		}
		return false;
	}
	
	@Override
	protected void onLayout(boolean change, int l, int t, int r, int b) {
		p("onLayout()");
//		headView.layout(0, headViewTop, viewWidth, 0);
	}
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		p("onMeasure");
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		viewHeight = getMeasuredHeight();
		viewWidth = getMeasuredWidth();
		itemWidth = viewWidth/N;
		childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(itemWidth, MeasureSpec.EXACTLY);
		childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
		measureFreshViewIfNotMeasured(widthMeasureSpec);
		measureLoadMoreViewIfNotMeasured(widthMeasureSpec);
		measureHeadView(widthMeasureSpec);
		initItems();
	}
	private int scrollDistance;
	
	@Override
	/**
	 * 调用scrollTo(int x, inty)和scrollBy(int x,int y)会执行到这里
	 */
	protected void onScrollChanged(int l, int t, int oldl, int oldt) {
		if(t==oldt) return;
		scrollDistance = t-curY;
		curY = t;
		isDownward = t<oldt;
		if(isDownward){//�?���?
			int topLimit = 0;
			if(isOnFling()){
				topLimit = flingTopLimit;
			}else if(scroller.isFinished()){
				topLimit = scrollTopLimit;
			}
			if(t<topLimit){
				scrollDistance = topLimit-curY;
				curY = topLimit;
				scrollTo(0, curY);
				if(!scroller.isFinished()){
					scroller.forceFinished(true);
				}
			}
		}else{//�?���?
			if(isAllItemsLoaded()){
				int bottomLimit = 0;
				if(isOnFling()){
					bottomLimit = flingBottomLimit;
				}else{
					bottomLimit = scrollBottomLimit;
				}
				if(curY>bottomLimit){
					scrollDistance = bottomLimit-curY;
					curY = bottomLimit;
					if(!scroller.isFinished()){
						scroller.forceFinished(true);
					}
				}
				scrollTo(0, curY);
			}
		}
		if(scrollDistance!=0){
			computeChildVisibity();
		}
		if(null!=stateListener){
			stateListener.onScroll(curY);
		}
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent e) {
		if(e.getAction()==MotionEvent.ACTION_UP){
			modifyOverBound();
		}
		return detector.onTouchEvent(e);
	}
	
	final private void p(String s){
//		System.out.println(s);
	}

	public void setAdapter(Adapter adapter){
		adapter.addObserver(this);
		this.adapter = adapter;
		requestLayout();
	}
	
	public void setCanFresh(boolean b){
		freshable = b;
	}
	
	public void setCanLoad(boolean b){
		loadable = b;
	}
	
	public void setColumn(int n){
		this.N = n;
		topItems = new Item[N];
		bottomItems = new Item[N];
	}
	/**
	 * 下拉刷新显示的View
	 */
	public void setFreshView(View v){
		freshView = v;
		addView(freshView);
	}
	/**
	 * 像ListView那样添加�?��HeadView，不过只能添加一�?
	 * @param headerView
	 */
	public void setHeadView(View v){
		headView = v;
		addView(headView);
	}
	/**
	 * 加载更多显示的View
	 */
	public void setLoadMoreView(View v){
		loadMoreView = v;
		addView(loadMoreView);
	}
	public void setStateListener(StateListener listener){
		this.stateListener = listener;
	}
	public void startFresh(){
		if(!isFreshing){
			scrollTopLimit = topBound;
			scroller.startScroll(0, curY, 0, topBound-curY);
			
			isFreshing = true;
			flingTopLimit = topBound;
			stateListener.startFresh();
			postInvalidate();
		}
	}
	@Override
	public void update(Observable observable, Object data){
		p("update()");
		if(null!=data){
			int position = (Integer) data;
			p("update() fresh item : position="+position);
			if(position<itemList.size()){
				if(isItemVisible(position, DEFAULT_EXTRA_SIZE)){
					Item item = itemList.get(position);
					adapter.getView(item.v, this, position);
				}
			}
		}else{
			switch(adapter.getUpdateMode()){
			case Adapter.MODE_UPDATE_APPEND:
				if(adapter.getCount()!=itemList.size()){
					initBottomConfigs();
					scrollBy(0, 1);//触发onScrollChanged()
				}
				break;
			case Adapter.MODE_UPDATE_ALL:
				p("update() WaterFallAdapter.MODE_UPDATE_ALL");
				reset();
				break;
			}
		}
	}


	private void reset() {
		itemRecycler.clear();
		for(View v : itemViewList){
			v.setVisibility(View.GONE);
			itemRecycler.add(v);
		}
		idleItemList.addAll(itemList);
		itemList.clear();
		isInitItemsDone = false;
		for(int i=0; i<N; i++){
			topItems[i] = null;
			bottomItems[i] = null;
		}
		initBottomConfigs();
		requestLayout();
	}
	
	
}
